home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH4 / SRC / BINCONT.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-01-03  |  20.0 KB  |  629 lines

  1. VERSION 4.00
  2. Begin VB.Form BinContForm 
  3.    Caption         =   "Binary Contrast"
  4.    ClientHeight    =   4110
  5.    ClientLeft      =   960
  6.    ClientTop       =   1470
  7.    ClientWidth     =   8010
  8.    Height          =   4800
  9.    Left            =   900
  10.    LinkTopic       =   "Form1"
  11.    ScaleHeight     =   274
  12.    ScaleMode       =   3  'Pixel
  13.    ScaleWidth      =   534
  14.    Top             =   840
  15.    Width           =   8130
  16.    Begin VB.PictureBox HistPict 
  17.       AutoRedraw      =   -1  'True
  18.       Height          =   2775
  19.       Left            =   4080
  20.       MousePointer    =   2  'Cross
  21.       ScaleHeight     =   181
  22.       ScaleMode       =   3  'Pixel
  23.       ScaleWidth      =   258
  24.       TabIndex        =   4
  25.       Top             =   0
  26.       Width           =   3930
  27.    End
  28.    Begin VB.PictureBox FromSwin 
  29.       Height          =   3855
  30.       Left            =   0
  31.       ScaleHeight     =   253
  32.       ScaleMode       =   3  'Pixel
  33.       ScaleWidth      =   245
  34.       TabIndex        =   2
  35.       Top             =   0
  36.       Width           =   3735
  37.       Begin VB.PictureBox FromPict 
  38.          AutoRedraw      =   -1  'True
  39.          AutoSize        =   -1  'True
  40.          Height          =   1905
  41.          Left            =   0
  42.          ScaleHeight     =   123
  43.          ScaleMode       =   3  'Pixel
  44.          ScaleWidth      =   88
  45.          TabIndex        =   3
  46.          Top             =   0
  47.          Width           =   1380
  48.       End
  49.    End
  50.    Begin VB.HScrollBar FromHBar 
  51.       Enabled         =   0   'False
  52.       Height          =   255
  53.       Left            =   0
  54.       TabIndex        =   1
  55.       Top             =   3840
  56.       Width           =   3765
  57.    End
  58.    Begin VB.VScrollBar FromVBar 
  59.       Enabled         =   0   'False
  60.       Height          =   3855
  61.       Left            =   3720
  62.       TabIndex        =   0
  63.       Top             =   0
  64.       Width           =   255
  65.    End
  66.    Begin MSComDlg.CommonDialog FileDialog 
  67.       Left            =   3840
  68.       Top             =   0
  69.       _Version        =   65536
  70.       _ExtentX        =   847
  71.       _ExtentY        =   847
  72.       _StockProps     =   0
  73.       CancelError     =   -1  'True
  74.    End
  75.    Begin VB.Menu mnuFile 
  76.       Caption         =   "&File"
  77.       Begin VB.Menu mnuFileLoad 
  78.          Caption         =   "&Load..."
  79.          Shortcut        =   ^L
  80.       End
  81.       Begin VB.Menu mnuFileSep2 
  82.          Caption         =   "-"
  83.       End
  84.       Begin VB.Menu mnuFileExit 
  85.          Caption         =   "E&xit"
  86.       End
  87.    End
  88. Attribute VB_Name = "BinContForm"
  89. Attribute VB_Creatable = False
  90. Attribute VB_Exposed = False
  91. Option Explicit
  92. Dim SysPalSize As Integer
  93. Dim NumStaticColors As Integer
  94. Dim StaticColor1 As Integer
  95. Dim StaticColor2 As Integer
  96. Dim LogPal As Integer
  97. Dim bytes() As Byte
  98. Dim wid As Long
  99. Dim hgt As Long
  100. Dim origpal(0 To 255) As PALETTEENTRY
  101. Dim newpal(0 To 255) As PALETTEENTRY
  102. Dim IndexCounts(0 To 255) As Long
  103. Dim ValueCounts(0 To 255) As Long
  104. Dim MaxBlack As Integer
  105. ' ************************************************
  106. ' Adjust the colors in the image so all those with
  107. ' original brightness greater than max_black are
  108. ' white and all others are black.
  109. ' ************************************************
  110. Sub SetBinaryContrast(pic As Control, max_black As Integer)
  111. Dim i As Integer
  112. Dim val As Integer
  113. Dim status As Long
  114.     MaxBlack = max_black
  115.     ' Remap the values in the logical palette.
  116.     For i = StaticColor1 + 1 To StaticColor2 - 1
  117.         ' Assumes this is a gray scale image.
  118.         If origpal(i).peRed > max_black Then
  119.             val = 255
  120.         Else
  121.             val = 0
  122.         End If
  123.         With newpal(i)
  124.             .peRed = val
  125.             .peGreen = val
  126.             .peBlue = val
  127.             .peFlags = PC_NOCOLLAPSE
  128.         End With
  129.     Next i
  130.     i = SetPaletteEntries(LogPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, newpal(StaticColor1 + 1))
  131.     i = RealizePalette(pic.hdc)
  132. End Sub
  133. ' ************************************************
  134. ' Return the index of the nonstatic gray closest
  135. ' to the given value (assuming the non-static
  136. ' colors are a gray scale created by
  137. ' MatchGrayPalette).
  138. ' ************************************************
  139. Function NearestNonstaticGray(c As Integer) As Integer
  140. Dim dgray As Single
  141.     If c < 0 Then
  142.         c = 0
  143.     ElseIf c > 255 Then
  144.         c = 255
  145.     End If
  146.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  147.     NearestNonstaticGray = c / dgray + StaticColor1 + 1
  148. End Function
  149. ' ************************************************
  150. ' Count the number of pixels with each palette
  151. ' index.
  152. ' ************************************************
  153. Sub CountIndexes()
  154. Dim X As Integer
  155. Dim Y As Integer
  156. Dim idx As Integer
  157.     ' Start from scratch.
  158.     For X = 0 To SysPalSize - 1
  159.         IndexCounts(X) = 0
  160.     Next X
  161.     ' Count the indexes.
  162.     For Y = 1 To hgt
  163.         For X = 1 To wid
  164.             idx = bytes(X, Y)
  165.             IndexCounts(idx) = IndexCounts(idx) + 1
  166.         Next X
  167.     Next Y
  168. End Sub
  169. ' ************************************************
  170. ' Count the brightness values.
  171. ' ************************************************
  172. Sub CountValues()
  173. Dim i As Integer
  174. Dim val As Integer
  175. Dim brightval As Integer
  176. Dim darkval As Integer
  177.     ' Start from scratch.
  178.     For i = 0 To SysPalSize - 1
  179.         ValueCounts(i) = 0
  180.     Next i
  181.     ' Add up the values.
  182.     '
  183.     ' For each palette index i, with brightness
  184.     ' val, there are IndexCounts(i) pixels with
  185.     ' that brightness.
  186.     For i = 0 To SysPalSize - 1
  187.         With origpal(i)
  188.             val = (CInt(.peRed) + .peGreen + .peBlue) / 3
  189.         End With
  190.         ValueCounts(val) = ValueCounts(val) + IndexCounts(i)
  191.     Next i
  192. End Sub
  193. ' ***********************************************
  194. ' Load the indicated file and prepare to work
  195. ' with its palette.
  196. ' ***********************************************
  197. Sub LoadFromPict(fname As String)
  198. Dim i As Integer
  199.     On Error GoTo LoadFileError
  200.     FromPict.Picture = LoadPicture(fname)
  201.     On Error GoTo 0
  202.     FromHBar.Enabled = False
  203.     FromVBar.Enabled = False
  204.     DoEvents
  205.     MatchGrayPalette FromPict
  206.     FromPict.Move 0, 0
  207.     ResetScrollBars
  208.     ' Make the new and original palettes match.
  209.     For i = 0 To SysPalSize - 1
  210.         newpal(i) = origpal(i)
  211.     Next i
  212.     ' Count the pixels with each palette index.
  213.     CountIndexes
  214.     ' Count the brightness values.
  215.     CountValues
  216.     ' Display the current histogram.
  217.     MaxBlack = -1
  218.     ShowHistogram
  219.     Caption = "Binary Contrast [" & fname & "]"
  220.     Exit Sub
  221. LoadFileError:
  222.     Beep
  223.     MsgBox "Error loading file " & fname & "." & _
  224.         vbCrLf & Error$
  225.     Exit Sub
  226. End Sub
  227. Private Sub Form_Unload(Cancel As Integer)
  228.     End
  229. End Sub
  230. ' ************************************************
  231. ' Present a message indicating the pixel's palette
  232. ' index and color value.
  233. ' ************************************************
  234. Private Sub FromPict_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  235.     If X > wid Or Y > hgt Then Exit Sub
  236.         
  237.     With newpal(bytes(X, Y))
  238.         MsgBox "Palette index:" & Str$(bytes(X, Y)) & _
  239.             vbCrLf & "Red:  " & Str$(.peRed) & _
  240.             vbCrLf & "Green:" & Str$(.peGreen) & _
  241.             vbCrLf & "Blue: " & Str$(.peBlue)
  242.     End With
  243. End Sub
  244. ' ***********************************************
  245. ' Load the control's palette so it matches the
  246. ' the system palette. Remap any of the image's
  247. ' pixels that use static colors to non-static
  248. ' colors.
  249. ' Set the following module global variables.
  250. '   LogPal      Image logical palette handle.
  251. '   origpal()  Image logical palette entries.
  252. '   wid         Width of image.
  253. '   hgt         Height of image.
  254. '   bytes(1 To wid, 1 To hgt)
  255. '               Image pixel values.
  256. ' ***********************************************
  257. Sub MatchColorPalette(pic As Control)
  258. Dim sys(0 To 255) As PALETTEENTRY
  259. Dim i As Integer
  260. Dim bm As BITMAP
  261. Dim hbm As Integer
  262. Dim status As Long
  263. Dim X As Integer
  264. Dim Y As Integer
  265. Dim clr As Integer
  266.     ' Make sure pic has the foreground palette.
  267.     pic.ZOrder
  268.     i = RealizePalette(pic.hdc)
  269.     DoEvents
  270.     ' Get the system palette entries.
  271.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sys(0))
  272.             
  273.     ' Make the logical palette as big as possible.
  274.     LogPal = pic.Picture.hPal
  275.     If ResizePalette(LogPal, SysPalSize) = 0 Then
  276.         Beep
  277.         MsgBox "Error resizing logical palette.", _
  278.             vbExclamation
  279.         Exit Sub
  280.     End If
  281.     ' Blank the non-static colors.
  282.     For i = 0 To StaticColor1
  283.         origpal(i) = sys(i)
  284.     Next i
  285.     For i = StaticColor1 + 1 To StaticColor2 - 1
  286.         With origpal(i)
  287.             .peRed = 0
  288.             .peGreen = 0
  289.             .peBlue = 0
  290.             .peFlags = PC_NOCOLLAPSE
  291.         End With
  292.     Next i
  293.     For i = StaticColor2 To 255
  294.         origpal(i) = sys(i)
  295.     Next i
  296.     i = SetPaletteEntries(LogPal, 0, SysPalSize, origpal(0))
  297.     ' Insert the non-static colors.
  298.     For i = StaticColor1 + 1 To StaticColor2 - 1
  299.         origpal(i) = sys(i)
  300.         origpal(i).peFlags = PC_NOCOLLAPSE
  301.     Next i
  302.     i = SetPaletteEntries(LogPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, origpal(StaticColor1 + 1))
  303.     ' Realize the new palette.
  304.     i = RealizePalette(pic.hdc)
  305.     ' Get the image pixels.
  306.     hbm = pic.Image
  307.     status = GetObject(hbm, BITMAP_SIZE, bm)
  308.     wid = bm.bmWidthBytes
  309.     hgt = bm.bmHeight
  310.     ReDim bytes(1 To wid, 1 To hgt)
  311.     status = GetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  312.     ' Remap any pixels using static colors.
  313.     For Y = 1 To hgt
  314.         For X = 1 To wid
  315.             clr = bytes(X, Y)
  316.             If clr <= StaticColor1 Or clr >= StaticColor2 Then
  317.                 With sys(clr)
  318.                     bytes(X, Y) = _
  319.                         NearestNonstaticColor( _
  320.                         .peRed, .peGreen, .peBlue)
  321.                 End With
  322.             End If
  323.         Next X
  324.     Next Y
  325.     ' Update the image's pixel values.
  326.     status = SetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  327.     pic.Refresh
  328. End Sub
  329. ' ***********************************************
  330. ' Load the control's palette so the non-static
  331. ' colors are grays. Map the logical palette to
  332. ' match the system palette. Convert the image to
  333. ' use the non-static grays.
  334. ' Set the following module global variables.
  335. '   LogPal      Image logical palette handle.
  336. '   origpal()  Image logical palette entries.
  337. '   wid         Width of image.
  338. '   hgt         Height of image.
  339. '   bytes(1 To wid, 1 To hgt)
  340. '               Image pixel values.
  341. ' ***********************************************
  342. Sub MatchGrayPalette(pic As Control)
  343. Dim sys(0 To 255) As PALETTEENTRY
  344. Dim i As Integer
  345. Dim bm As BITMAP
  346. Dim hbm As Integer
  347. Dim status As Long
  348. Dim X As Integer
  349. Dim Y As Integer
  350. Dim gray As Single
  351. Dim dgray As Single
  352. Dim c As Integer
  353. Dim clr As Integer
  354.     ' Make sure pic has the foreground palette.
  355.     pic.ZOrder
  356.     i = RealizePalette(pic.hdc)
  357.     DoEvents
  358.     ' Get the system palette entries.
  359.     i = GetSystemPaletteEntries(pic.hdc, 0, SysPalSize, sys(0))
  360.         
  361.     ' Get the image pixels.
  362.     hbm = pic.Image
  363.     status = GetObject(hbm, BITMAP_SIZE, bm)
  364.     wid = bm.bmWidthBytes
  365.     hgt = bm.bmHeight
  366.     ReDim bytes(1 To wid, 1 To hgt)
  367.     status = GetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  368.     ' Make the logical palette as big as possible.
  369.     LogPal = pic.Picture.hPal
  370.     If ResizePalette(LogPal, SysPalSize) = 0 Then
  371.         Beep
  372.         MsgBox "Error resizing logical palette.", _
  373.             vbExclamation
  374.         Exit Sub
  375.     End If
  376.     ' Blank the non-static colors.
  377.     For i = 0 To StaticColor1
  378.         origpal(i) = sys(i)
  379.     Next i
  380.     For i = StaticColor1 + 1 To StaticColor2 - 1
  381.         With origpal(i)
  382.             .peRed = 0
  383.             .peGreen = 0
  384.             .peBlue = 0
  385.             .peFlags = PC_NOCOLLAPSE
  386.         End With
  387.     Next i
  388.     For i = StaticColor2 To 255
  389.         origpal(i) = sys(i)
  390.     Next i
  391.     i = SetPaletteEntries(LogPal, 0, SysPalSize, origpal(0))
  392.     ' Insert the non-static grays.
  393.     gray = 0
  394.     dgray = 255 / (StaticColor2 - StaticColor1 - 2)
  395.     For i = StaticColor1 + 1 To StaticColor2 - 1
  396.         c = gray
  397.         gray = gray + dgray
  398.         With origpal(i)
  399.             .peRed = c
  400.             .peGreen = c
  401.             .peBlue = c
  402.         End With
  403.     Next i
  404.     i = SetPaletteEntries(LogPal, StaticColor1 + 1, StaticColor2 - StaticColor1 - 1, origpal(StaticColor1 + 1))
  405.     ' Recreate the image using the new colors.
  406.     For Y = 1 To hgt
  407.         For X = 1 To wid
  408.             clr = bytes(X, Y)
  409.             With sys(clr)
  410.                 c = (CInt(.peRed) + .peGreen + .peBlue) / 3
  411.             End With
  412.             bytes(X, Y) = NearestNonstaticGray(c)
  413.         Next X
  414.     Next Y
  415.     status = SetBitmapBits(hbm, wid * hgt, bytes(1, 1))
  416.     ' Realize the gray palette.
  417.     i = RealizePalette(pic.hdc)
  418.     pic.Refresh
  419. End Sub
  420. ' ************************************************
  421. ' Return the index of the nonstatic color closest
  422. ' to the given color value.
  423. ' ************************************************
  424. Function NearestNonstaticColor(ByVal r As Integer, ByVal g As Integer, ByVal b As Integer) As Integer
  425. Dim best_i As Integer
  426. Dim best_dist As Long
  427. Dim dist As Long
  428. Dim dr As Long
  429. Dim dg As Long
  430. Dim db As Long
  431. Dim i As Integer
  432.     best_dist = 1000000
  433.     For i = StaticColor1 + 1 To StaticColor2 - 1
  434.         With origpal(i)
  435.             dr = r - .peRed
  436.             dg = g - .peGreen
  437.             db = b - .peBlue
  438.             dist = dr * dr + dg * dg + db * db
  439.         End With
  440.         If best_dist > dist Then
  441.             best_i = i
  442.             best_dist = dist
  443.         End If
  444.     Next i
  445.     NearestNonstaticColor = best_i
  446. End Function
  447. ' ************************************************
  448. ' Create a brightness histogram for the image.
  449. ' ************************************************
  450. Sub ShowHistogram()
  451. Dim i As Integer
  452. Dim maxy As Single
  453. Dim yscale As Single
  454.     HistPict.Cls
  455.     HistPict.Refresh
  456.     ' **********************
  457.     ' * Display the output *
  458.     ' **********************
  459.     For i = 0 To SysPalSize - 1
  460.         If maxy < ValueCounts(i) Then _
  461.             maxy = ValueCounts(i)
  462.     Next i
  463.     If maxy <> 0 Then
  464.         yscale = -HistPict.ScaleHeight / maxy
  465.     Else
  466.         yscale = 0
  467.     End If
  468.     maxy = HistPict.ScaleTop + HistPict.ScaleHeight
  469.     For i = 0 To SysPalSize - 1
  470.         HistPict.Line (i + 1, maxy)-Step(0, ValueCounts(i) * yscale)
  471.     Next i
  472.     ' Draw a line at the cutoff.
  473.     If MaxBlack >= 0 Then _
  474.         HistPict.Line (MaxBlack + 1, 0)- _
  475.             Step(0, HistPict.ScaleHeight), vbRed
  476. End Sub
  477. ' ***********************************************
  478. ' Set the Max and LargeChange properties for the
  479. ' image scroll bars.
  480. ' ***********************************************
  481. Sub ResetScrollBars()
  482.     ' FromHBar.
  483.     FromHBar.Value = 0
  484.     If FromSwin.ScaleWidth >= FromPict.Width Then
  485.         FromHBar.Enabled = False
  486.     Else
  487.         FromHBar.Max = FromPict.Width - FromSwin.ScaleWidth
  488.         FromHBar.LargeChange = FromSwin.ScaleWidth
  489.         FromHBar.Enabled = True
  490.     End If
  491.     ' FromVBar.
  492.     FromVBar.Value = 0
  493.     If FromSwin.ScaleHeight >= FromPict.Height Then
  494.         FromVBar.Enabled = False
  495.     Else
  496.         FromVBar.Max = FromPict.Height - FromSwin.ScaleHeight
  497.         FromVBar.LargeChange = FromSwin.ScaleHeight
  498.         FromVBar.Enabled = True
  499.     End If
  500. End Sub
  501. ' ***********************************************
  502. ' Give the form and all the picture boxes an
  503. ' hourglass cursor.
  504. ' ***********************************************
  505. Sub WaitStart()
  506.     MousePointer = vbHourglass
  507.     FromPict.MousePointer = vbHourglass
  508.     HistPict.MousePointer = vbHourglass
  509.     DoEvents
  510. End Sub
  511. ' ***********************************************
  512. ' Restore the mouse pointers for the form and all
  513. ' the picture boxes.
  514. ' ***********************************************
  515. Sub WaitEnd()
  516.     MousePointer = vbDefault
  517.     FromPict.MousePointer = vbDefault
  518.     HistPict.MousePointer = vbDefault
  519. End Sub
  520. Private Sub Form_Load()
  521.     ' Make sure the screen supports palettes.
  522.     If Not GetDeviceCaps(hdc, RASTERCAPS) And RC_PALETTE Then
  523.         Beep
  524.         MsgBox "This monitor does not support palettes.", _
  525.             vbCritical
  526.         End
  527.     End If
  528.     ' Get system palette size and # static colors.
  529.     SysPalSize = GetDeviceCaps(hdc, SIZEPALETTE)
  530.     NumStaticColors = GetDeviceCaps(hdc, NUMRESERVED)
  531.     StaticColor1 = NumStaticColors \ 2 - 1
  532.     StaticColor2 = SysPalSize - NumStaticColors \ 2
  533.     ' Remove the borders from FromPict.
  534.     FromPict.BorderStyle = vbTransparent
  535.     ' Make sure FromPict has control.
  536.     FromPict.ZOrder
  537. End Sub
  538. ' ***********************************************
  539. ' Make the picture as large as possible.
  540. ' ***********************************************
  541. Private Sub Form_Resize()
  542. Const GAP = 4
  543. Dim hgt As Single
  544. Dim wid As Single
  545.     If WindowState = vbMinimized Then Exit Sub
  546.         
  547.     hgt = ScaleHeight - FromHBar.Height - 1
  548.     wid = ScaleWidth - FromVBar.Width - 1 - _
  549.         GAP - HistPict.Width
  550.     ' Place FromSwin and its scroll bars.
  551.     FromSwin.Move 0, 0, wid, hgt
  552.     FromVBar.Move _
  553.         FromSwin.Left + FromSwin.Width + 1, _
  554.         0, FromVBar.Width, hgt
  555.     FromHBar.Move _
  556.         FromSwin.Left, FromSwin.Height + 1, _
  557.         wid
  558.     ' Place HistPict.
  559.     HistPict.Move FromVBar.Left + FromVBar.Width + GAP, 0
  560.     ' Set the scroll bar limits.
  561.     ResetScrollBars
  562. End Sub
  563. ' ***********************************************
  564. ' Move FromPict within FromSwin.
  565. ' ***********************************************
  566. Private Sub FromHBar_Change()
  567.     FromPict.Left = -FromHBar.Value
  568. End Sub
  569. ' ***********************************************
  570. ' Move FromPict within FromSwin.
  571. ' ***********************************************
  572. Private Sub FromHBar_Scroll()
  573.     FromPict.Left = -FromHBar.Value
  574. End Sub
  575. ' ************************************************
  576. ' Set the binary contrast cutoff at this X value.
  577. ' ************************************************
  578. Private Sub HistPict_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  579.     If X > 255 Then X = 256
  580.     SetBinaryContrast FromPict, X - 1
  581.     ShowHistogram
  582. End Sub
  583. ' ***********************************************
  584. ' Load a new image file.
  585. ' ***********************************************
  586. Private Sub mnuFileLoad_Click()
  587. Dim fname As String
  588.     ' Allow the user to pick a file.
  589.     On Error Resume Next
  590.     FileDialog.filename = "*.BMP;*.ICO;*.RLE;*.WMF;*.DIB"
  591.     FileDialog.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  592.     FileDialog.ShowOpen
  593.     If Err.Number = cdlCancel Then
  594.         Exit Sub
  595.     ElseIf Err.Number <> 0 Then
  596.         Beep
  597.         MsgBox "Error selecting file.", , vbExclamation
  598.         Exit Sub
  599.     End If
  600.     On Error GoTo 0
  601.     fname = Trim$(FileDialog.filename)
  602.     FileDialog.InitDir = Left$(fname, Len(fname) _
  603.         - Len(FileDialog.FileTitle) - 1)
  604.     ' Load the picture.
  605.     WaitStart
  606.     DoEvents
  607.     LoadFromPict fname
  608.     WaitEnd
  609. End Sub
  610. ' ***********************************************
  611. ' End the application. (See also the QueryUnload
  612. ' event.)
  613. ' ***********************************************
  614. Private Sub mnuFileExit_Click()
  615.     Unload Me
  616. End Sub
  617. ' ***********************************************
  618. ' Move FromPict within FromSwin.
  619. ' ***********************************************
  620. Private Sub FromVBar_Change()
  621.     FromPict.Top = -FromVBar.Value
  622. End Sub
  623. ' ***********************************************
  624. ' Move FromPict within FromSwin.
  625. ' ***********************************************
  626. Private Sub FromVBar_Scroll()
  627.     FromPict.Top = -FromVBar.Value
  628. End Sub
  629.